#include "ExampleModuleC.h"
#include "ExampleModuleS.h"
#include "ExampleModuleI.h"
#include <CORBA.h>
#include <PortableGroupC.h>
#include <iostream>
#include <FT_ReplicationManagerC.h>

class ExampleImpl : public POA_ExampleModule::Example {
  public:
    ExampleImpl(const std::string& id) : id_(id) {}

    void say_hello() override {
        std::cout << "Hello from ExampleImpl! Instance ID: " << id_ << std::endl;
    }

  private:
    std::string id_;
};

int main(int argc, char* argv[]) {
    try {
        CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

        // 获取 RootPOA 和 POAManager
        CORBA::Object_var poa_obj = orb->resolve_initial_references("RootPOA");
        PortableServer::POA_var poa = PortableServer::POA::_narrow(poa_obj);
        PortableServer::POAManager_var poa_manager = poa->the_POAManager();

        // 获取 FT_ReplicationManager
        CORBA::Object_var replication_manager_obj = orb->resolve_initial_references("ReplicationManager");
        FT::ReplicationManager_var replication_manager = FT::ReplicationManager::_narrow(replication_manager_obj);

        // 激活 POAManager
        poa_manager->activate();

        // 创建对象副本
        ExampleImpl* example_impl1 = new ExampleImpl("Replica1");
        ExampleImpl* example_impl2 = new ExampleImpl("Replica2");

        // 激活对象
        PortableServer::ObjectId_var id1 = poa->activate_object(example_impl1);
        PortableServer::ObjectId_var id2 = poa->activate_object(example_impl2);

        CORBA::Object_var example_obj1 = example_impl1->_this();
        CORBA::Object_var example_obj2 = example_impl2->_this();

        // 创建对象组
        PortableGroup::Properties prop_seq(1);
        prop_seq.length(1);
        prop_seq[0].nam.length(1);
        prop_seq[0].nam[0].id = CORBA::string_dup("org.omg.ft.MinimumNumberReplicas");
        prop_seq[0].val <<= (CORBA::UShort)2;

        PortableGroup::Criteria criteria;
        criteria.length(1);
        criteria[0].nam.length(1);
        criteria[0].nam[0].id = CORBA::string_dup("org.omg.PortableGroup.MembershipStyle");
        criteria[0].val <<= (CORBA::UShort)PortableGroup::MEMB_APP_CTRL;

        PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id;
        CORBA::Object_var object_group =
            replication_manager->create_object("IDL:ExampleModule/Example:1.0", prop_seq, factory_creation_id.out());

        //// 加入对象副本到对象组
        replication_manager->add_member(object_group.in(), prop_seq[0].nam, example_obj1);
        replication_manager->add_member(object_group.in(), prop_seq[0].nam, example_obj2);

        // 将对象组绑定到名称服务
        CORBA::Object_var naming_context_obj = orb->resolve_initial_references("NameService");
        CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow(naming_context_obj);

        CosNaming::Name name;
        name.length(1);
        name[0].id = CORBA::string_dup("ExampleGroup");

        naming_context->rebind(name, object_group);

        std::cout << "Server is running..." << std::endl;
        orb->run();
    } catch (const CORBA::Exception& ex) {
        std::cerr << "CORBA exception: " << ex << std::endl;
    }
    return 0;
}
